package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"sync"

	"data-treating/pkg/analysis"
	"data-treating/pkg/types"

	"github.com/gorilla/mux"
	"github.com/gorilla/websocket"
)

// ClientInfo 客户端信息
type ClientInfo struct {
	PersonID string `json:"person_id"`
	TaskID   string `json:"task_id"`
}

// WebServer Web服务器
type WebServer struct {
	analyzer     *analysis.PoseAnalyzer
	upgrader     websocket.Upgrader
	clients      map[*websocket.Conn]*ClientInfo
	clientsMutex sync.RWMutex
	poseHistory  map[string][]PoseDataWithAnalysis // 按任务ID分组的历史数据
	historyMutex sync.RWMutex
}

// PoseDataWithAnalysis 包含分析结果的姿势数据
type PoseDataWithAnalysis struct {
	PersonID  string                    `json:"person_id"` // 人员ID
	TaskID    string                    `json:"task_id"`   // 任务ID
	PoseData  types.PoseData            `json:"pose_data"`
	Analysis  *types.PoseAnalysisResult `json:"analysis"`
	Timestamp int64                     `json:"timestamp"`
	FrameID   int                       `json:"frame_id"`
}

// NewWebServer 创建新的Web服务器
func NewWebServer() *WebServer {
	return &WebServer{
		analyzer: analysis.NewPoseAnalyzer(),
		upgrader: websocket.Upgrader{
			CheckOrigin: func(r *http.Request) bool {
				return true // 允许所有来源
			},
			EnableCompression: true,
			ReadBufferSize:    1024,
			WriteBufferSize:   1024,
		},
		clients:     make(map[*websocket.Conn]*ClientInfo),
		poseHistory: make(map[string][]PoseDataWithAnalysis),
	}
}

// Start 启动Web服务器
func (ws *WebServer) Start(port string) error {
	r := mux.NewRouter()

	// 静态文件服务
	r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

	// API路由
	r.HandleFunc("/", ws.handleHome).Methods("GET")

	// 处理姿势数据 - 支持人员ID和任务ID
	r.HandleFunc("/api/pose", ws.handlePoseData).Methods("POST")
	// 处理校准数据 - 支持人员ID
	r.HandleFunc("/api/calibrate", ws.handleCalibrate).Methods("POST")
	// 获取历史数据 - 支持任务ID
	r.HandleFunc("/api/history", ws.handleGetHistory).Methods("GET")

	// 抖动过滤相关API
	r.HandleFunc("/api/v1/filter/smoothing-factor", ws.handleSetSmoothingFactor).Methods("POST")
	r.HandleFunc("/api/v1/filter/history-size", ws.handleSetHistorySize).Methods("POST")
	r.HandleFunc("/api/v1/filter/clear-history", ws.handleClearHistory).Methods("POST")
	r.HandleFunc("/api/v1/config/filter-settings", ws.handleGetFilterSettings).Methods("GET")

	// 处理WebSocket连接
	r.HandleFunc("/ws", ws.handleWebSocket)

	// 启动服务器
	fmt.Printf("Web服务器启动在 http://localhost%s\n", port)
	return http.ListenAndServe(port, r)
}

// handleHome 处理主页
func (ws *WebServer) handleHome(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, "static/index.html")
}

// handlePoseData 处理姿势数据
func (ws *WebServer) handlePoseData(w http.ResponseWriter, r *http.Request) {
	var request struct {
		PersonID string         `json:"person_id"`
		TaskID   string         `json:"task_id"`
		PoseData types.PoseData `json:"pose_data"`
	}

	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		http.Error(w, "Invalid JSON", http.StatusBadRequest)
		return
	}

	// 验证必需参数
	if request.PersonID == "" || request.TaskID == "" {
		http.Error(w, "person_id and task_id are required", http.StatusBadRequest)
		return
	}

	// 设置当前人员ID
	calibrator := ws.analyzer.GetCalibrator()
	calibrator.SetCurrentPerson(request.PersonID)

	// 分析姿势
	var analysisResult *types.PoseAnalysisResult
	var smoothedPose types.PoseData
	var err error

	if calibrator.GetCalibrationData().Calibrated {
		// 获取去抖动后的数据
		smoothedPose = ws.analyzer.GetSmoothedPose(request.PoseData)

		// 使用去抖动后的数据进行分析
		analysisResult, err = ws.analyzer.AnalyzePose(smoothedPose)
		if err != nil {
			analysisResult = &types.PoseAnalysisResult{
				Timestamp:  request.PoseData.Timestamp,
				Confidence: 0.0,
			}
		}
	} else {
		smoothedPose = request.PoseData
		analysisResult = &types.PoseAnalysisResult{
			Timestamp:  request.PoseData.Timestamp,
			Confidence: 0.0,
		}
	}

	// 创建包含分析结果的数据
	poseWithAnalysis := PoseDataWithAnalysis{
		PersonID:  request.PersonID,
		TaskID:    request.TaskID,
		PoseData:  request.PoseData,
		Analysis:  analysisResult,
		Timestamp: request.PoseData.Timestamp,
		FrameID:   request.PoseData.FrameID,
	}

	// 添加到历史记录
	ws.historyMutex.Lock()
	if ws.poseHistory[request.TaskID] == nil {
		ws.poseHistory[request.TaskID] = make([]PoseDataWithAnalysis, 0)
	}
	ws.poseHistory[request.TaskID] = append(ws.poseHistory[request.TaskID], poseWithAnalysis)
	// 保持最近100帧的历史记录
	if len(ws.poseHistory[request.TaskID]) > 100 {
		ws.poseHistory[request.TaskID] = ws.poseHistory[request.TaskID][len(ws.poseHistory[request.TaskID])-100:]
	}
	ws.historyMutex.Unlock()

	// 广播到相关WebSocket客户端
	ws.broadcastPoseData(poseWithAnalysis)

	// 返回响应
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"success":       true,
		"person_id":     request.PersonID,
		"task_id":       request.TaskID,
		"analysis":      analysisResult,
		"smoothed_pose": smoothedPose,
	})
}

// handleCalibrate 处理校准请求
func (ws *WebServer) handleCalibrate(w http.ResponseWriter, r *http.Request) {
	log.Printf("开始处理校准请求")

	var request struct {
		PersonID string           `json:"person_id"`
		PoseData []types.PoseData `json:"pose_data"`
	}

	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		log.Printf("JSON解析失败: %v", err)
		http.Error(w, "Invalid JSON", http.StatusBadRequest)
		return
	}

	log.Printf("接收到校准请求: person_id=%s, frames=%d", request.PersonID, len(request.PoseData))

	// 验证必需参数
	if request.PersonID == "" {
		log.Printf("person_id为空")
		http.Error(w, "person_id is required", http.StatusBadRequest)
		return
	}

	// 设置当前人员ID
	calibrator := ws.analyzer.GetCalibrator()
	calibrator.SetCurrentPerson(request.PersonID)
	log.Printf("已设置当前人员ID: %s", request.PersonID)

	// 重置校准器
	calibrator.ResetCalibration()
	log.Printf("已重置校准器")

	// 添加校准数据
	log.Printf("开始添加校准数据...")
	validFrames := 0
	for i, pose := range request.PoseData {
		if calibrator.AddCalibrationFrame(pose) {
			validFrames++
		} else {
			log.Printf("第%d帧数据无效，跳过", i+1)
		}
	}
	log.Printf("成功添加%d帧有效数据", validFrames)

	// 检查是否可以进行校准
	if !calibrator.IsCalibrationReady() {
		log.Printf("校准未就绪，需要至少%d帧数据", 10)
		http.Error(w, "Insufficient frames for calibration", http.StatusBadRequest)
		return
	}

	log.Printf("开始执行校准...")
	// 执行校准
	if err := calibrator.PerformCalibration(); err != nil {
		log.Printf("校准失败: %v", err)
		http.Error(w, "Calibration failed: "+err.Error(), http.StatusInternalServerError)
		return
	}

	log.Printf("校准完成成功")
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"success":     true,
		"message":     "Calibration completed successfully",
		"person_id":   request.PersonID,
		"frames_used": validFrames,
	})
}

// handleGetHistory 获取历史数据
func (ws *WebServer) handleGetHistory(w http.ResponseWriter, r *http.Request) {
	taskID := r.URL.Query().Get("task_id")
	if taskID == "" {
		http.Error(w, "task_id is required", http.StatusBadRequest)
		return
	}

	ws.historyMutex.RLock()
	history, exists := ws.poseHistory[taskID]
	ws.historyMutex.RUnlock()

	if !exists {
		history = make([]PoseDataWithAnalysis, 0)
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"task_id": taskID,
		"history": history,
	})
}

// handleWebSocket 处理WebSocket连接
func (ws *WebServer) handleWebSocket(w http.ResponseWriter, r *http.Request) {
	// 获取查询参数
	personID := r.URL.Query().Get("person_id")
	taskID := r.URL.Query().Get("task_id")

	log.Printf("WebSocket连接请求: person_id=%s, task_id=%s", personID, taskID)

	if personID == "" || taskID == "" {
		log.Printf("WebSocket连接失败: person_id或task_id为空")
		http.Error(w, "person_id and task_id are required", http.StatusBadRequest)
		return
	}

	// 升级HTTP连接到WebSocket
	conn, err := ws.upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Printf("WebSocket upgrade failed: %v", err)
		return
	}

	log.Printf("WebSocket连接成功建立: person_id=%s, task_id=%s", personID, taskID)

	// 添加客户端
	ws.clientsMutex.Lock()
	ws.clients[conn] = &ClientInfo{
		PersonID: personID,
		TaskID:   taskID,
	}
	ws.clientsMutex.Unlock()

	// 发送历史数据
	ws.historyMutex.RLock()
	if history, exists := ws.poseHistory[taskID]; exists && len(history) > 0 {
		// 发送最近10帧数据
		start := len(history) - 10
		if start < 0 {
			start = 0
		}
		recentHistory := history[start:]
		conn.WriteJSON(map[string]interface{}{
			"type": "history",
			"data": recentHistory,
		})
	}
	ws.historyMutex.RUnlock()

	// 处理连接关闭
	defer func() {
		ws.clientsMutex.Lock()
		delete(ws.clients, conn)
		ws.clientsMutex.Unlock()
		conn.Close()
		log.Printf("WebSocket连接已关闭: person_id=%s, task_id=%s", personID, taskID)
	}()

	// 保持连接活跃
	for {
		_, _, err := conn.ReadMessage()
		if err != nil {
			log.Printf("WebSocket读取消息失败: %v", err)
			break
		}
	}
}

// broadcastPoseData 广播姿势数据到相关WebSocket客户端
func (ws *WebServer) broadcastPoseData(data PoseDataWithAnalysis) {
	ws.clientsMutex.RLock()
	defer ws.clientsMutex.RUnlock()

	message := map[string]interface{}{
		"type": "pose_data",
		"data": data,
	}

	for client, clientInfo := range ws.clients {
		// 只发送给相同任务ID的客户端
		if clientInfo.TaskID == data.TaskID {
			err := client.WriteJSON(message)
			if err != nil {
				log.Printf("Failed to send message to client: %v", err)
				client.Close()
				delete(ws.clients, client)
			}
		}
	}
}

// handleSetSmoothingFactor 设置平滑因子
func (ws *WebServer) handleSetSmoothingFactor(w http.ResponseWriter, r *http.Request) {
	var request struct {
		Factor float64 `json:"factor"`
	}

	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		http.Error(w, "Invalid JSON", http.StatusBadRequest)
		return
	}

	ws.analyzer.SetSmoothingFactor(request.Factor)

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"success": true,
		"message": "Smoothing factor updated successfully",
		"factor":  request.Factor,
	})
}

// handleSetHistorySize 设置历史记录大小
func (ws *WebServer) handleSetHistorySize(w http.ResponseWriter, r *http.Request) {
	var request struct {
		Size int `json:"size"`
	}

	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		http.Error(w, "Invalid JSON", http.StatusBadRequest)
		return
	}

	ws.analyzer.SetHistorySize(request.Size)

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"success": true,
		"message": "History size updated successfully",
		"size":    request.Size,
	})
}

// handleClearHistory 清除历史记录
func (ws *WebServer) handleClearHistory(w http.ResponseWriter, r *http.Request) {
	ws.analyzer.ClearHistory()

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"success": true,
		"message": "History cleared successfully",
	})
}

// handleGetFilterSettings 获取过滤设置
func (ws *WebServer) handleGetFilterSettings(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"smoothing_factor": ws.analyzer.GetSmoothingFactor(),
		"history_size":     ws.analyzer.GetHistorySize(),
	})
}

func main() {
	server := NewWebServer()
	log.Fatal(server.Start(":8080"))
}
